home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
prog
/
asm_n_z.arj
/
SD2.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-05-15
|
15KB
|
412 lines
;------------------------------------------------------------------------------;
; ;
; ;
; ;
; Switch Directory - SD ;
; ;
; ;
; ;
;Usage ;
; ;
; [d:\....]>SD [drive][switch][subdirectory name] ;
; ;
; [drive] - the drive to search (if not searhing ;
; current drive) ;
; ;
; [switch] = blank - search whole disk ;
; ;
; = \ - search only subdirectories of the ;
; current directory ;
; ;
; = / - search only one path deep. Searches ;
; the root directory only. (Similar ;
; to DOS CD command with one pathname) ;
; ;
; ;
; ;
; [subdirectory name] - the name of an individual ;
; subdirectory (not the ;
; complete path) ;
; ;
; If the command line is left blank then you are ;
; taken to the root directory of the disk ;
; ;
; ;
;Sorce code heavily dependent on Vern Buerg's LDIR program. Thanks Vern ;
; ;
;3/11/87 - Stephen Falatko ;
; ;
;Written for the A86 assembler ;
; ;
;------------------------------------------------------------------------------;
; Simple change directory
CODE SEGMENT
Org 0100
Stackx Dw 0 ;Entry stack pointer
Mov Stackx,SP ;Save stack ptr for exiting
Jmp Start
;
; Data Areas, Constants, Etc.
LF Equ 10
CR Equ 13
Stopper Equ 255 ;Ends print strings
CURDSK Equ 019 ;Get current disk
SETDTA Equ 01A ;Set data transfer area
CHDIR Equ 03B ;Change directory
GETPATH Equ 047 ;Get current directory
Errlvl Db 0 ;DOS return code
RootFlag Db 0
OneDeepFlag Db 0
Sub_Dir Db 16 Dup (0) ;The sub dir we want to change to
Done_Flag Dw 0
Count Dw 0 ;Number of args on command line
DtaPointer Dw DtaAreaBegin
Direction Db 0
BackOneDir Db '..',0
SearchAsciiZ Db '*.*',0
;
; Headings and titles
Not_Found_Msg Db CR,LF,'Subdirectory Not Found',CR,LF,Stopper
PathErrorMsg Db CR,LF,'Illegal \ charater in path name',CR,LF,Stopper
Help Db CR,LF,'Usage:',CR,LF,CR,LF
Db '[d:\....]>SD [drive][switch][subdirectory name]',CR,LF
Db ' [drive] - the drive to search. (if not searching',CR,LF
Db ' current drive)',CR,LF,CR,LF
Db ' [switch] = blank - search whole disk',CR,LF,CR,LF
Db ' = \ - search only subdirectories of the',CR,LF
Db ' current directory',CR,LF,CR,LF
Db ' = / - search only one path deep. Searches',CR,LF
Db ' the root directory only. (Similar',CR,LF
Db ' to DOS CD command with one pathname)',CR,LF,CR,LF
Db ' [subdirectory name] - the name of an individual',CR,LF
Db ' subdirectory (not the',CR,LF
Db ' complete path)',CR,LF
Db ' If the command line is left blank then you are',CR,LF
Db ' taken to the root directory of the disk',CR,LF,Stopper
OrigDr Db 'x:' ;Original drive
OrigDir Db '\',63 Dup (0) ; and path
RootDir Db 'x:\',0 ;To get vol label
;
; Set default drive and path
Start:
Mov AH,0D ; Reset diskettes
Int 021
Mov AH,CURDSK ; Get current disk
Int 021
Add AL,'A'
Mov OrigDr,AL ; Save original drive letter
Mov RootDir,AL ;
Mov AH,GETPATH ; Save original path
Mov DL,OrigDr
Sub DL,'@' ; a little monkey business to set
Mov SI,Offset OrigDir + 1 ; the original drive
Int 021
Mov AX,02523 ; set Ctrl+Break vector to point
Mov DX,Offset NFCB ; to our not found. This way a Ctrl+Brk
Int 021 ; will leave us in the place we started
Sub CX,CX ; Clear CX
Mov CL,B [080] ; Get the number of characters in
Cmp CX,0 ; Anything?
Jne L1
Call No_Arg ;set root dir and leave
Jmp Exit
L1:
Mov SI,081 ; set up to parse command line
Mov DI,Offset Sub_dir
Push DI
Mov DI,SI
Mov al,':' ;drive specifier present?
Repne Scasb
Cmp B [DI-1],':'
Jne L10
Mov SI,DI ;point SI to character following :
Sub DI,2 ;point DI to drive letter
Mov AL,B [DI]
Xor AL,020
Mov RootDir,AL
Sub DX,DX
Mov AH,0E ; set drive
Mov DL,AL
Sub DL,'A'
Int 021
Cmp B [SI],CR
If e Call No_Arg
Pop DI
Jmp Short L2
L10:
Pop DI
L2:
Lodsb
Cmp AL,' ' ;strip leading blanks
Jz L2
Cmp AL,0D ;carriage return
Jz L7
Cmp AL,'?' ;?
Jne L3
Cmp DI,Offset Sub_Dir ;still pointing to beginning?
Jne L3
Mov DX,Offset Help
Call PrintS
Jmp Exit ;load next
L3:
Cmp AL,'/' ;/ ?
Jne L30
Cmp DI,Offset Sub_Dir ;still pointing to beginning?
Jne L30
Mov OneDeepFlag,1 ;set flag so we only search one deep
Jmp Short L2 ;load next
L30:
Cmp AL,'\' ;\ ?
Jne L4
Cmp DI,Offset Sub_Dir ;still pointing to beginning?
Jne L31
Mov RootFlag,1 ;set flag so we won't set to root
Jmp Short L2 ;load next
L31:
Jmp Short PathError ;nope, ERROR!
L4:
Cmp RootFlag,1 ;been here before?
Je L5 ;yep, go on
Push AX
Call No_Arg ;no, set to root directory
Pop Ax
Mov RootFlag,1 ;set flag
L5:
Cmp AL,'0' ;compare with 0
Jb L2 ;get next char if smaller
Cmp AL,'z' ;compare with z
Ja L2 ;get next char if bigger
Cmp AL,'a' ;lowercase letter?
Jb L6 ;nope so go on
Xor AL,020 ;make upper case
L6:
Stosb
Jmp Short L2
L7:
Mov Count,DI ;how many characters stored?
Sub Count,Offset Sub_Dir
Cmp Count,0
Je Exit
Mov AL,0
Stosb
Call GetDir ; Read the directory
Cmp Done_Flag,1
Jne Not_Found
Jmp Short Exit
Not_Found:
Mov DX,Offset Not_Found_Msg
Call PrintS
NFCB:
Sub DX,DX
Mov DL,OrigDr
Cmp DL,RootDir
Je NF1
Mov AH,0E ; set drive
Sub DL,'A'
Int 021
NF1:
Mov AH,CHDIR ;Set path to original path
Mov DX,Offset OrigDr
Int 021
Jmp Short Exit
PathError:
Mov DX,Offset PathErrorMsg
Call PrintS
Exit:
Mov SP,Stackx ;Insure exiting stack
Done: Mov AL,Errlvl ;Return to system
Mov AH,04C ; via EXIT
Int 021
;
;
; Start at Root Directory
No_Arg:
; If no argument then set current
Mov AH,CHDIR ; path to root directory
Mov DX,Offset RootDir
Int 021
Ret
;
;
; Search for matching sub directory
GetDir:
Mov Done_Flag,0
; Find first or next subdirectory level
; -------------------------------------
NextLevel:
Mov DX,[DTAPointer] ; Next nested DTA
Mov AH,1Ah ; For DOS call to set DTA
Int 21h ; Do it
Cmp [Direction],0 ; Check if we're nesting
Jnz FindNextFile ; If not, we're continuing
Mov DX,Offset SearchAsciiZ ; We search for *.*
Mov CX,10h ; Subdirectory attribute
Mov AH,4Eh ; Find first file
Int 21h ; by calling DOS
Jmp Short TestMatch ; Hop around next section
FindNextFile:
Mov AH,4Fh ; Find next file
Int 21h ; by calling DOS
TestMatch:
Jc NoMoreFiles ; If CY flag, at end of rope
Mov BX,[DTAPointer] ; Our find stuff is here
Test B [BX + 21],10h ; Test if directory attribute
Jz FindNextFile ; If not, continue search
Add BX,30 ; Now points to directory name
Cmp Byte Ptr [BX],'.' ; Ignore "." and ".." entries
Jz FindNextFile ; by continuing the search
Cmp OneDeepFlag,1 ; looking only at this dir?
Je Compare
Push BX ; save pointer to subdir name
Mov DX,BX ; Now DX points to found dir
Mov AH,3Bh ; Set up DOS function call
Int 21h ; And change directory
Pop BX ; get pointer to subdir name back
Compare:
Push CX ;check to see if its the path we want
Push SI
Push DI
Sub CX,CX
Mov CX,Count
Mov DI, Offset Sub_Dir
Lea SI, BX
Repe Cmpsb
Pop DI
Pop SI
Pop CX
Jz Found ; matched up so leave
Cmp OneDeepFlag,1
Jne GoOn
Mov [Direction],-1
Jmp Short NextLevel
GoOn:
Add [DtaPointer],43 ; New DTA for new level
Mov [Direction],0 ; I.E., Find first file
Jmp NextLevel ; All ready to cycle through
; No More Files Found -- go back to previous level
; ------------------------------------------------
NoMoreFiles:
Cmp [DTAPointer],Offset DtaAreaBegin ; See if back at start
Jz ExitGD ; If so, that's all, folks
Sub [DTAPointer],43 ; Back one for previous
Mov [Direction],-1 ; I.E., will find next file
Mov DX,Offset BackOneDir ; The string ".."
Mov AH,3Bh ; Call to change directory
Int 21h ; Change directory to father
Jmp NextLevel ; And continue the search
Found:
Cmp OneDeepFlag,1
If ne Jmp Short F1
Mov DX,BX ; Now DX points to found dir
Mov AH,3Bh ; Set up DOS function call
Int 21h ; And change directory
F1:
Mov Done_Flag,1
ExitGD:
Ret
;
;
; Print String like INT 21H function 9
PrintS: ; DX has offset to string
Push SI ; ending in char x'FF'
Push BX
Push CX
Mov SI,DX ; Ptr to string text
Sub CX,CX ; Overall text length
PS1: Lodsb
Cmp AL,Stopper ; Ending hex FF?
Je PS9
Inc CX
Jmp Short PS1
PS9:
Mov BX,1 ; Standard output device
Mov AH,40h ; to write to
Int 21h
Pop CX ; Recover registers
Pop BX
Pop SI
Ret
DtaAreaBegin equ $ ; is also the DTA area
DtaAreaEnd equ DtaAreaBegin + 32 * 43 ; Can have 32 DTAs of 43 bytes